﻿using NetTopologySuite.Utilities;
using Serilog;
using Serilog.Debugging;
using Serilog.Events;
using Serilog.Formatting.Json;
using Serilog.Sinks.Elasticsearch;
using Serilog.Sinks.File;
using Serilog.Sinks.SystemConsole.Themes;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sustainalytics.Utils.Serilog
{
    public class ControversiesServiceSerilog
    {
        public static Lazy<ControversiesServiceSerilog> _lazyLog = new Lazy<ControversiesServiceSerilog>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);
        private readonly ILogger _logger;


        public static ControversiesServiceSerilog Log
        {
            get
            {
                return _lazyLog.Value;
            }
        }

        public static ControversiesServiceSerilog InitLog()
        {
            var log = new ControversiesServiceSerilog();
            return log;

        }

        public ControversiesServiceSerilog()
        {
            var loggerConfig = new LoggerConfiguration()
                  .MinimumLevel.Debug()
                  .WriteTo.Console(theme: SystemConsoleTheme.Literate)
                  .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200")) // for the docker-compose implementation
                  {
                      IndexFormat = "testpi-{0:yyyy.MM.dd}",
                      AutoRegisterTemplate = true,
                      //BufferBaseFilename = "./buffer",
                      RegisterTemplateFailure = RegisterTemplateRecovery.IndexAnyway,
                      FailureCallback = e => Console.WriteLine("Unable to submit event " + e.MessageTemplate),
                      EmitEventFailure = EmitEventFailureHandling.WriteToSelfLog |
                                         EmitEventFailureHandling.WriteToFailureSink |
                                         EmitEventFailureHandling.RaiseCallback,
                      FailureSink = new FileSink("../failuresControversies-" + DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss") + ".txt", new JsonFormatter(), null)
                  });
            _logger = loggerConfig.CreateLogger();

            SelfLog.Enable(Console.Error);
        }

        public void Exception(Exception ex)
        {
            if (ex != null)
                this.Exception(ex.GetType().ToString(), ex.Message, ex.ToString());
        }
        public void Exception(string exceptionType, string exceptionMessage, string exceptionInformation)
        {
            var eventId = 2;
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error("Exception {evenId}, {exceptiontype}, {exceptionMessage}, {exceptionInformation}", eventId, exceptionType, exceptionMessage, exceptionInformation);

        }

        public void ApplicationStartError(Exception ex)
        {
            var eventId = 3;
            string formatedmessage = String.Format("ApplicationStartError  {0}, {1}, {2}", eventId, ex.GetType().ToString(), ex.Message);

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }

        public void ApplicationStopError(Exception ex)
        {
            var eventId = 4;
            string formatedmessage = String.Format("ApplicationStoptError  {0}, {1}, {2}", eventId, ex.GetType().ToString(), ex.Message);

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }

        public void OnUnhandledDomainException(Exception ex)
        {
            var eventId = 5;
            string formatedmessage = String.Format("UnhandledDomainException  {0}, {1}, {2}", eventId, ex.GetType().ToString(), ex.Message);

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }

        public void GetCompanyReportIdAsSuccess(Guid companyId)
        {
            var eventId = 6;
            string formatedmessage = String.Format("GetCompanyReportSuccess ControversyReport {0}, {1}, {2}", eventId, companyId, DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss"));

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void GetCompanyReportIdAsError(Guid companyId, Exception ex)
        {
            var eventId = 7;
            string formatedmessage = String.Format("GetCompanyReportError ControversyReport {0}, {1}, {2}, {3}", eventId, companyId, ex.Message, DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss"));

            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }

        public void GetcomparisonGroupControversiesSuccess(Guid companyId, Guid controversyindicatorId)
        {
            var eventId = 8;
            string formatedmessage = String.Format("GetcomparisonGroup Controversies Success {0}, {1}, {2}, {3}", eventId, companyId, controversyindicatorId, DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss"));

            if (_logger.IsEnabled(LogEventLevel.Information))
                _logger.Information(formatedmessage);
        }

        public void GetcomparisonGroupControversiesError(Guid companyId, Guid controversyindicatorId, Exception ex)
        {
            var eventId = 9;
            string formatedmessage = String.Format("GetcomparisonGroup Controversies Error {0}, {1}, {2}, {3}, {4}", eventId, companyId, controversyindicatorId, ex.Message, DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss"));
            if (_logger.IsEnabled(LogEventLevel.Error))
                _logger.Error(formatedmessage);
        }

    }
}
